﻿using System.Collections.Generic;
using Home.Haushalt.Lib;
using System;
using System.Linq;
using System.Windows.Forms;
using System.Data;
using System.Drawing;
using Home.Haushalt.Lib.Element;

namespace Home.Haushalt.Gui
{
    /// <summary>
    /// 
    /// </summary>
    public class WindowController
    {
        /// <summary></summary>
        public static List<FrmGridForm> _gridForms = new List<FrmGridForm>();

        /// <summary></summary>
        public static List<FrmProperty> _propertyForms = new List<FrmProperty>();

        /// <summary></summary>
        public static FrmGridForm FistGridForm { get { return _gridForms.First(); } }

        public static List<ElementBase> ElementHistory = new List<ElementBase>();

        /// <summary>
        /// 
        /// </summary>
        /// <param name="elementTypeName"></param>
        public static void UpdateElementLayoutMenu(Type elementType)
        {
            foreach (FrmGridForm frm in _gridForms)
            {
                frm.UpdateElementLayoutMenu(elementType);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public static void SetStatusImage()
        {
            foreach (FrmGridForm frm in _gridForms)
            {
                frm.SetStatusImage();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="elementType"></param>
        public static void RefreshGrids(Type elementType)
        {
            foreach (FrmGridForm frm in _gridForms)
            {
                foreach (Control subctrl in frm.Controls)
                {
                    RefreshGrids(subctrl, elementType);
                }
            }

            foreach (FrmProperty frm in _propertyForms)
            {
                foreach (Control subctrl in frm.Controls)
                {
                    RefreshGrids(subctrl, elementType);
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="ctrl"></param>
        /// <param name="elementType"></param>
        private static void RefreshGrids(Control ctrl, Type elementType)
        {
            if (ctrl is HGrid)
            {
                HGrid grid = ctrl as HGrid;
                if (grid.ElementType != null && grid.ElementType.Equals(elementType))
                {
                    grid.CalculateUnboundFields();
                    grid.InitializeRowsAppearances();
                    grid.DisplayLayout.Bands[0].SortedColumns.RefreshSort(false);
                    grid.DisplayLayout.RefreshFilters();

                    grid.OnGridRefresh();

                    return;
                }
            }
            //if (ctrl is HComboBox)
            //{
            //    HComboBox comboBox = ctrl as HComboBox;
            //    if (comboBox.ParentElementType != null && comboBox.ParentElementType.Equals(elementType.Name))
            //    {
            //        comboBox.DataSourceBind();
            //    }
            //}
            else if (ctrl != null && ctrl.Controls != null)
            {
                foreach (Control subctrl in ctrl.Controls)
                {
                    RefreshGrids(subctrl, elementType);
                }
            }

        }

        /// <summary>
        /// 
        /// </summary>
        public static void Reset()
        {
            CloseAll();

            List<Type> elementTypes = ElementHistory.Select(item => item.GetType()).Distinct().ToList();
            ElementHistory.Clear();

            elementTypes.ForEach(item => UpdateElementLayoutMenu(item));

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="rows"></param>
        private static void AddElementToHistory(ElementBase elementObject)
        {
            List<ElementBase> elements = ElementHistory.Where(item => item.GetType().Equals(elementObject.GetType())).ToList();

            //Nach dem Element in History suchen
            ElementBase existsElement = elements.Where(item => item.ID.Equals(elementObject.ID)).FirstOrDefault();
            if (existsElement != default(ElementBase))
            {
                //Löschen um umzusortieren
                ElementHistory.Remove(existsElement);
            }

            //An Anfang hinzufügen
            ElementHistory.Insert(0, elementObject);

            //Nur vordefinierte Zahl von Historyeinträge zulassen
            if (elements.Count > DAO.Settings.Selected.ElementHistoryCount)
            {
                ElementHistory.Remove(elements.Last());
            }

            //Alle relevanten Fenster aktualisieren
            UpdateElementLayoutMenu(elementObject.GetType());
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="control"></param>
        /// <param name="row"></param>
        /// <returns></returns>
        public static FrmProperty EditElementProperty(Control control, DataRow row)
        {
            return EditElementProperty(control, new DataRow[] { row }.ToList());
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="control"></param>
        /// <param name="rows"></param>
        /// <returns></returns>
        public static FrmProperty EditElementProperty(Control control, List<DataRow> rows)
        {
            FrmProperty frmProperty = FrmProperty.Instantiate(rows);

            if (frmProperty != null)
            {
                if (frmProperty.SingleSelection)
                {
                    AddElementToHistory(frmProperty.ElementObject);
                }

                frmProperty.OnChanged += new EventHandler<HEventArgs>(frmProperty_OnChanged);

                //ParentForm finden um die zentralle Positionierung des PropertyForms zu erreichen
                Form parentForm = FindParentForm(control);

                if (parentForm != null)
                {
                    frmProperty.Location = new Point(parentForm.Left + 50, parentForm.Top + 50);
                }

                frmProperty.Show();
            }

            return frmProperty;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void frmProperty_OnChanged(object sender, HEventArgs e)
        {
            Type type = sender.GetType();

            RefreshGrids(type);

            if (type.Equals(Date.ElementType))
            {
                RefreshGrids(Posten.ElementType);
            }

            DAO.MonthbalanceCollection.DataBind();
            RefreshMonthbalanceGrids();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="control"></param>
        /// <returns></returns>
        public static Form FindParentForm(Control control)
        {
            Form parentForm = null;
            if (control is Form)
            {
                parentForm = (Form)control;
            }
            else if (control.Parent is Form)
            {
                parentForm = (Form)control.Parent;
            }
            else if (control.Parent is Control)
            {
                parentForm = FindParentForm(control.Parent);
            }

            return parentForm;
        }

        /// <summary>
        /// 
        /// </summary>
        public static void RefreshMonthbalanceGrids()
        {
            _gridForms.ForEach(item => FindAllMonthbalanceForms(item.Controls).ForEach(mForm => mForm.WindowControllerUpdate()));
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="controls"></param>
        /// <returns></returns>
        private static List<UcGridFormMonthbalance> FindAllMonthbalanceForms(System.Windows.Forms.Control.ControlCollection controls)
        {
            List<UcGridFormMonthbalance> result = new List<UcGridFormMonthbalance>();

            foreach (Control ctrl in controls)
            {
                if (ctrl is UcGridFormMonthbalance)
                {
                    result.Add((UcGridFormMonthbalance)ctrl);
                }
                else
                {
                    result.AddRange(FindAllMonthbalanceForms(ctrl.Controls));
                }
            }

            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="form"></param>
        public static void Register(FrmGridForm form)
        {
            if (!_gridForms.Contains(form))
            {
                _gridForms.Add(form);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="form"></param>
        public static void Unregister(FrmGridForm form)
        {
            if (_gridForms.Contains(form))
            {
                _gridForms.Remove(form);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="form"></param>
        public static void Register(FrmProperty form)
        {
            if (!_propertyForms.Contains(form))
            {
                _propertyForms.Add(form);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="form"></param>
        public static void Unregister(FrmProperty form)
        {
            if (_propertyForms.Contains(form))
            {
                _propertyForms.Remove(form);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public static void CloseAll()
        {
            //Alle (ausser Hauptdialog) Element-Sicht-Dialogs schliessen
            while (_gridForms.Count > 1) //weil LoginForm muss nicht geschlossen werden
            {
                _gridForms[_gridForms.Count - 1].Close();
            }

            //Alle Element-Eigenschaften-Dialogs schliessen
            while (_propertyForms.Count > 0)
            {
                _propertyForms[0].Close();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public static void CloseApplication()
        {
            _gridForms[0].Close();
        }

    }
}
